class myPromise {
	constructor(fn) {
		this.pending = "pending"; // 初始化状态
		this.fulfilled = "fulfilled"; // 成功状态
		this.rejected = "rejected"; // 失败状态

		this.curState = "pending"; // 当前状态
		this.val = null; // 成功值
		this.res = null; // 失败值

		// 结合发布订阅模式，完成异步任务的执行
		this.onFulfilledCallbacks = []; // 用来接收成功回调函数
		this.onRejectedCallbacks = []; // 用来接收失败回调函数

		// class的this指向问题，这里用bind进行解决（或者也可以使用箭头函数来定义函数进行解决）
		fn(this.resolve.bind(this), this.reject.bind(this));
	}

	// 成功操作
	resolve(val) {
		if (this.curState === this.pending) {
			// 改变状态pending => fulfilled
			this.curState = this.fulfilled;
			// 接收数据
			this.val = val;
			// 进行发布，即触发订阅者的所有回调函数
			this.onFulfilledCallbacks.forEach((fn) => fn(val));
		}
	}
	// 失败操作
	reject(res) {
		if (this.curState === this.pending) {
			// 改变状态pending => rejected
			this.curState = this.rejected;
			// 接收错误原因
			this.res = res;
			// 进行发布，即触发订阅者的所有回调函数
			this.onRejectedCallbacks.forEach((fn) => fn(res));
		}
	}

	// 链式调用
	then(onFulfilledCallback, onRejectedCallback) {
		// 如果接收的不是函数，则封装成函数
		onFulfilledCallback =
			typeof onFulfilledCallback === "function"
				? onFulfilledCallback
				: function (val) {
						this.resolve(val);
				  };
		onRejectedCallback =
			typeof onRejectedCallback === "function"
				? onRejectedCallback
				: function (err) {
						throw err;
				  };

		// 链式调用操作
		let self = this;

		// 当前状态为fulfilled
		if (self.curState === self.fulfilled) {
			return new myPromise((resolve, reject) => {
				try {
					let p = onFulfilledCallback(self.val);
					p instanceof myPromise ? p.then(resolve, reject) : resolve(p);
				} catch (err) {
					reject(err);
				}
			});
		}

		// 当前状态为rejected
		if (self.curState === self.rejected) {
			return new myPromise((resolve, reject) => {
				try {
					let p = onRejectedCallback(self.res);
					p instanceof myPromise ? p.then(resolve, reject) : resolve(p);
				} catch (err) {
					reject(err);
				}
			});
		}

		// 当前状态为pending
		if (self.curState === self.pending) {
			return new myPromise((resolve, reject) => {
				self.onFulfilledCallbacks.push(() => {
					try {
						let x = onFulfilledCallback(self.val);
						x instanceof myPromise
							? x.then(resolve, reject)
							: resolve(self.val);
					} catch (err) {
						reject(err);
					}
				});
				self.onRejectedCallbacks.push(() => {
					try {
						let x = onRejectedCallback(self.res);
						x instanceof myPromise
							? x.then(resolve, reject)
							: resolve(self.res);
					} catch (err) {
						reject(err);
					}
				});
			});
		}
	}
	// 捕捉异常
	catch(fn) {
		return this.then(null, fn);
	}
}

let p1 = new myPromise((resolve, reject) => {
	setTimeout(() => {
		resolve(111);
		reject(222);
	}, 1000);
});
p1.then((val) => {
	console.log(val);
	return val;
})
	.then((val) => console.log(val))
	.catch((err) => {
		console.log(err);
	});
